#include "stdafx.h"
#include "roles/player/playermgr.h"
#include "../gamemgr.h"
#include "../gamewrapper.h"
#include "./playermodepage.h"

#define HP_OFFSET_POSX 3
#define HP_OFFSET_POSY 1

PlayerModePage::PlayerModePage(string resultBkg, Point resultPos, string strAIDir)
: m_playerCount(0)
, m_pReadyHelper(NULL)
, m_pStageObj(NULL)
, m_pResultPage(NULL)
{
	m_pStageObj = new StageObj(GameMgr::GetInstance().GetStageDepth());
	m_pStageObj->OnMenuClick += EventObject<OnStageBtnMenuClickFunc>(this, &PlayerModePage::OnBtnMenuClick);

	InitPlayers(strAIDir);

	m_pReadyHelper = new ReadyHelper(GameMgr::GetInstance().GetStageSize());
	m_pReadyHelper->OnEnd += EventObject<OnReadyEndFunc>(this, &PlayerModePage::OnReadyEnd);

	m_pResultPage = new PixelBitmap(resultBkg, resultPos, GameMgr::GetInstance().GetStageDepth() - 2);
	m_pResultPage->SetVisible(false);

	StatMgr::GetInstance().OnStatEnd += EventObject<OnStatEndFunc>(this, &PlayerModePage::OnStatEnd);
}

PlayerModePage::~PlayerModePage()
{
	StatMgr::GetInstance().OnStatEnd -= EventObject<OnStatEndFunc>(this, &PlayerModePage::OnStatEnd);
	PlayerMgr::GetInstance().Stop();
	StatMgr::GetInstance().Stop();

	delete m_pReadyHelper;
	m_pReadyHelper = NULL;

	delete m_pStageObj;
	m_pStageObj = NULL;

	delete m_pResultPage;
	m_pResultPage = NULL;

	for (size_t i = 0; i < m_textlist.size(); ++i)
	{
		delete m_textlist[i];
		m_textlist[i] = NULL;
	}

	m_textlist.clear();
}

void PlayerModePage::InitPlayers(string strLuaDir)
{
	ScriptMgr::GetInstance().ReadLuaFiles(strLuaDir);
	m_playerCount = ScriptMgr::GetInstance().GetLuaFileCount();

	vector3d* playerPos = new vector3d[m_playerCount];
	Color* colors = new Color[m_playerCount];

	for (size_t i = 0; i < m_playerCount; ++i)
	{
		//set color
		if (i == 0)
		{
			Color color1(255, 0, 0);
			memcpy(colors + i, &color1, sizeof(Color));
		}
		else if (i == 1)
		{
			Color color2(0, 200, 0);
			memcpy(colors + i, &color2, sizeof(Color));
		}
		else if (i == 2)
		{
			Color color3(0, 0, 255);
			memcpy(colors + i, &color3, sizeof(Color));
		}
		else if (i >= 3)
		{
			Color color4(0, 0, 0);
			memcpy(colors + 3, &color4, sizeof(Color));
		}
	}

	if (m_playerCount == 1)
	{
		vector3d pos1 = {50., 50., 0.};
		memcpy(playerPos, pos1, sizeof(vector3d));
	}
	else if (m_playerCount == 2)
	{
		vector3d pos1 = {25., 50., 0.};
		memcpy(playerPos, pos1, sizeof(vector3d));

		vector3d pos2 = {75., 50., 180.};
		memcpy(playerPos + 1, pos2, sizeof(vector3d));
	}
	else if (m_playerCount == 3)
	{
		vector3d pos1 = {15., 30., 30.};
		memcpy(playerPos, pos1, sizeof(vector3d));

		vector3d pos2 = {85., 30., 150.};
		memcpy(playerPos + 1, pos2, sizeof(vector3d));

		vector3d pos3 = {50., 85., -90.};
		memcpy(playerPos + 2, pos3, sizeof(vector3d));
	}
	else if (m_playerCount >= 4)
	{
		vector3d pos1 = {25., 25., 45.};
		memcpy(playerPos, pos1, sizeof(vector3d));

		vector3d pos2 = {25., 75., -45.};
		memcpy(playerPos + 1, pos2, sizeof(vector3d));

		vector3d pos3 = {75., 25., 135.};
		memcpy(playerPos + 2, pos3, sizeof(vector3d));

		vector3d pos4 = {75., 75., -135.};
		memcpy(playerPos + 3, pos4, sizeof(vector3d));
	}

	Size stageSize = GameMgr::GetInstance().GetStageSize();

	int hpcx = 0, hpcy = 0;
	HpObj::GetSize(hpcy, hpcy);

	Point hpPos;
	hpPos.x = HP_OFFSET_POSX;

	for (size_t i = 0; i < m_playerCount; ++i)
	{
		//filt ".lua"
		string strFileName = ScriptMgr::GetInstance().GetFileName(i);
		strFileName = strFileName.substr(0, strFileName.length() - 4);

		//load script
		ScriptMgr::GetInstance().LoadScript(strFileName, i);

		hpPos.y = stageSize.cx - HP_OFFSET_POSY - hpcy;

		Point startPos(playerPos[i][0], playerPos[i][1]);
		float z = playerPos[i][2];

		PlayerMgr::GetInstance().AddPlayer(strFileName, startPos, z, hpPos, stageSize.cy, colors[i]);
		StatMgr::GetInstance().AddPlayer(strFileName, colors[i]);
		hpPos.x += hpcx + HP_OFFSET_POSX + 10;
	}

	m_pStageObj->SetPlayerLights(playerPos, m_playerCount);

	ScriptMgr::GetInstance().ClearFiles();
}

void PlayerModePage::OnReadyEnd()
{
	//Start Player AI
	GameWrapper::UpdatePlayersTbl();

	PlayerMgr::GetInstance().Start();
	StatMgr::GetInstance().SetMinPlayerCount(1);
	StatMgr::GetInstance().Start();
	m_pStageObj->StartLights();
}

void PlayerModePage::OnStatEnd(int playerCount, StatData* pStatDatas)
{
	m_pStageObj->ShutDownStage();
	m_pResultPage->SetVisible(true);

	//Show Result Text
	for (int i = 0; i < playerCount; ++i)
	{
		StatData* pStatData = pStatDatas + i;
		
		//player name
		TextObj* pTextNameBkg = new TextObj(pStatData->strName, Point(7.7, 57.8 - 10.5 * i), GameMgr::GetInstance().GetStageDepth() - 1, 12, Color(255, 255, 255));
		TextObj* pTextName = new TextObj(pStatData->strName, Point(7.5, 58 - 10.5 * i), GameMgr::GetInstance().GetStageDepth(), 12, pStatData->color);
		m_textlist.push_back(pTextNameBkg);
		m_textlist.push_back(pTextName);

		//player bullets count
		TextObj* pTextBulletsBkg = new TextObj(StrUtils::IntToString(pStatData->bulletCount), Point(25.2, 57.8 - 10.5 * i), GameMgr::GetInstance().GetStageDepth() - 1, 12, Color(255, 255, 255));
		TextObj* pTextBullets = new TextObj(StrUtils::IntToString(pStatData->bulletCount), Point(25, 58 - 10.5 * i), GameMgr::GetInstance().GetStageDepth(), 12, pStatData->color);
		m_textlist.push_back(pTextBulletsBkg);
		m_textlist.push_back(pTextBullets);

		//hitted_player name
		TextObj* pTextHittedNameBkg = new TextObj(pStatData->strName, Point(33.3 + 12 * i, 66.8), GameMgr::GetInstance().GetStageDepth() - 1, 12, Color(255, 255, 255));
		TextObj* pTextHittedName = new TextObj(pStatData->strName, Point(33 + 12 * i, 67), GameMgr::GetInstance().GetStageDepth(), 12, pStatData->color);
		m_textlist.push_back(pTextHittedNameBkg);
		m_textlist.push_back(pTextHittedName);

		int hittedcount = 0;

		//hitted bullets count
		for (int y = 0; y < playerCount; ++y)
		{
			//hitted_player name
			TextObj* pTextHittedBulletsBkg = new TextObj(StrUtils::IntToString(pStatData->hittedCount[y]), Point(38.7 + 12 * y, 57.8 - 10.5 * i), GameMgr::GetInstance().GetStageDepth() - 1, 12, Color(255, 255, 255));
			TextObj* pTextHittedBullets = new TextObj(StrUtils::IntToString(pStatData->hittedCount[y]), Point(38.6 + 12 * y, 58 - 10.5 * i), GameMgr::GetInstance().GetStageDepth(), 12, pStatData->color);
			m_textlist.push_back(pTextHittedBulletsBkg);
			m_textlist.push_back(pTextHittedBullets);

			hittedcount += pStatData->hittedCount[y];
		}

		//hitted percent
		float percent = pStatData->bulletCount == 0 ? 0 : hittedcount / (float)pStatData->bulletCount;
		static char percentbuf[256];
		sprintf_s(percentbuf, 256, "%.2f%%", percent * 100);

		TextObj* pTextPercentBkg = new TextObj(percentbuf, Point(85.2, 57.8 - 10.5 * i), GameMgr::GetInstance().GetStageDepth() - 1, 12, Color(255, 255, 255));
		TextObj* pTextPercent = new TextObj(percentbuf, Point(85, 58 - 10.5 * i), GameMgr::GetInstance().GetStageDepth(), 12, pStatData->color);
		m_textlist.push_back(pTextPercentBkg);
		m_textlist.push_back(pTextPercent);

	}
}

void PlayerModePage::OnBtnMenuClick()
{
	FireEvent(OnPageBackClickFunc, OnMenuClick, ());
}